/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Engine2D.renderer;

import Engine2D.graphics.GLColour;
import Engine2D.graphics.GLSpriteSheet;
import java.nio.FloatBuffer;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.omg.PortableInterceptor.NON_EXISTENT;

/**
 *
 * @author Garys
 */
public class VertexArrayRenderer extends DefaultRenderer {

    private static final int TOLERANCE = 20;
    /**
     * 
     */
    public static final int MAX_VERTS = 5000;
    /**
     * 
     */
    public static final int NONE = -1;
    private int geomType = -1;
    private int vertIndex;
    private float[] color = new float[]{1f, 1f, 1f, 1f};
    
	private float[] tex = new float[] {0f,0f};
    private float[] verts = new float[MAX_VERTS * 3];
    private float[] cols = new float[MAX_VERTS * 4];
    private float[] texs = new float[MAX_VERTS * 3];
    private FloatBuffer vertices = BufferUtils.createFloatBuffer(MAX_VERTS * 3);
    private FloatBuffer colors = BufferUtils.createFloatBuffer(MAX_VERTS * 4);
    private FloatBuffer textures = BufferUtils.createFloatBuffer(MAX_VERTS * 2);
    private int listMode = 0;

    /**
     * 
     * @param width
     * @param height
     */
    public void initDisplay(int width, int height) {
        super.initDisplay(width, height);

        startBuffer();
        glEnableClientState(GLRenderer.GL_VERTEX_ARRAY);
        glEnableClientState(GLRenderer.GL_TEXTURE_COORD_ARRAY);
        glEnableClientState(GLRenderer.GL_COLOR_ARRAY);
    }

    /**
     * 
     * @param verts
     */
    public void setVerts(float[] verts) {
        this.verts = verts;
        this.texs = verts;
        this.cols = verts;
     
    }

    private void startBuffer() {
        vertIndex = 0;
    }

    private void flushBuffer() {
        if (vertIndex == 0) {
            System.out.println("hello1");
            return;
        }
        if (this.geomType == NONE) {
            System.out.println("hello2");
            return;
        }

        if (vertIndex < TOLERANCE) {
            glBegin(geomType);
            for (int i = 0; i < vertIndex; i++) {
                System.out.println("hello");
                glColor4f(color[0], color[1], color[2], color[3]);
                glTexCoord2f(texs[(i * 2) + 0], texs[(i * 2) + 1]);
                glVertex3f(verts[(i * 3) + 0], verts[(i * 3) + 1], verts[(i * 3) + 2]);
            }
            
            glEnd();
            geomType = NONE;
            return;
        }
        vertices.clear();
        colors.clear();
        textures.clear();

        vertices.put(verts, 0, vertIndex * 3);
        colors.put(cols, 0, vertIndex * 4);
        textures.put(texs, 0, vertIndex * 2);

        vertices.flip();
        colors.flip();
        textures.flip();

        glVertexPointer(3, 0, vertices);
        glColorPointer(4, 0, colors);
        glTexCoordPointer(2, 0, textures);

        glDrawArrays(geomType, 0, vertIndex);
        geomType = NONE;
    }

    private void applyBuffer() {
        if (listMode > 0) {
            return;
        }

        if (vertIndex != 0) {
            flushBuffer();
            startBuffer();
        }

        super.glColor4f(color[0], color[1], color[2], color[3]);
    }

    /**
     * 
     * @param args
     */
    public static void main(String[] args) {
        VertexArrayRenderer render = new VertexArrayRenderer();

        
        render.initDisplay(800, 600);
        
        Random rand = new Random();


        while (true) {
            try {
                Thread.sleep(0);
                Display.update();
                GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

                GLSpriteSheet.getInstance().bind();
                render.setVerts(new float[]{1f, 45f, 65f, 78f, 89f, 123f, 466f, 565f, 563f, 14f, 345f, 465f, 178f, 189f, 143f, 446f, 367f, 760f });
                render.setColour(new GLColour(1f, 0.5f, 0.3f, 1f));
                
                
                render.flush();

            } catch (InterruptedException ex) {
                Logger.getLogger(DefaultRenderer.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
    }

    private void setColour(GLColour gLColour) {
        this.color[0] = gLColour.getRed();
        this.color[1] = gLColour.getGreen();
        this.color[2] = gLColour.getBlue();
        this.color[3] = gLColour.getAlpha();

        for (int i = 0; i < cols.length; i++) {
        }

    }

    /**
     * 
     * @param geomType
     */
    public void glBegin(int geomType) {
        if (listMode > 0) {
            super.glBegin(geomType);
            return;
        }

        if (this.geomType != geomType) {
            applyBuffer();
            this.geomType = geomType;
        }
    }
    
    /**
     * 
     */
    public void flush() {
		super.flush();
		
		applyBuffer();
	}
    
    /**
     * 
     * @param x
     * @param y
     * @param z
     */
    public void glVertex3f(float x, float y, float z) {
		if (listMode > 0) {
			super.glVertex3f(x,y,z);
			return;
		}
		
		verts[(vertIndex*3)+0] = x;
		verts[(vertIndex*3)+1] = y;
		verts[(vertIndex*3)+2] = z;
		cols[(vertIndex*4)+0] = color[0];
		cols[(vertIndex*4)+1] = color[1];
		cols[(vertIndex*4)+2] = color[2];
		cols[(vertIndex*4)+3] = color[3];
		texs[(vertIndex*2)+0] = tex[0];
		texs[(vertIndex*2)+1] = tex[1];
		vertIndex++;
		
		
	}
}
